﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Collections.ObjectModel;
using HigLabo.WindowsAzure.RestService.Extensions;

namespace HigLabo.WindowsAzure.RestService.ServiceManagement
{
    public class Deployment
    {
        public static readonly String ElementName = "Deployment";

        public String Name { get; private set; }
        public DeploymentSlot? DeploymentSlot { get; private set; }
        public String PrivateID { get; private set; }
        public DeploymentStatus? Status { get; private set; }
        public String Label { get; private set; }
        public String Url { get; private set; }
        public String Configuration { get; private set; }
        public Int32 UpgradeDomainCount { get; private set; }
        public String SdkVersion { get; private set; }
        public Boolean Locked { get; private set; }
        public Boolean RollbackAllowed { get; private set; }
        public UpgradeStatus UpgradeStatus { get; private set; }

        private Collection<RoleInstance> _RoleInstanceList = new Collection<RoleInstance>();
        private Collection<Role> _RoleList = new Collection<Role>();
        private Collection<InputEndpoint> _InputEndpointList = new Collection<InputEndpoint>();

        public IEnumerable<RoleInstance> RoleInstanceList
        {
            get { foreach (var item in _RoleInstanceList) { yield return item; } }
        }
        public IEnumerable<Role> RoleList
        {
            get { foreach (var item in _RoleList) { yield return item; } }
        }
        public IEnumerable<InputEndpoint> InputEndpointList
        {
            get { foreach (var item in _InputEndpointList) { yield return item; } }
        }

        public Deployment(XElement xml)
        {
            XElement el;
            IEnumerable<XElement> els;
            if (xml == null)
            {
                throw new ArgumentNullException("xml");
            }
            /*Deployment*/
            this.Name = xml.ValueOrEmpty("Name");
            this.DeploymentSlot = xml.ValueToEnum<DeploymentSlot>("DeploymentSlot");
            this.PrivateID = xml.ValueOrEmpty("PrivateID");
            this.Status = xml.ValueToEnum<DeploymentStatus>("Status");
            this.Label = xml.ValueOrEmpty("Label");
            this.Label = Base64Converter.From(this.Label);
            this.Url = xml.ValueOrEmpty("Url");
            this.Configuration = xml.ValueOrEmpty("Configuration");
            this.Configuration = Base64Converter.From(this.Configuration);
            this.UpgradeDomainCount = xml.ValueToInt32("UpgradeDomainCount", 0);
            this.SdkVersion = xml.ValueOrEmpty("SdkVersion");
            this.Locked = xml.ValueToBoolean("Locked", false);
            this.RollbackAllowed = xml.ValueToBoolean("RollbackAllowed", false);
            /*RoleInstance*/
            el = xml.ElementByLocalName("RoleInstanceList");
            if (el != null)
            {
                els = el.ElementsByLocalName(RoleInstance.ElementName);
                foreach (var item in els)
                {
                    el = item;
                    var add = new RoleInstance(el);
                    this._RoleInstanceList.Add(add);
                }
            }
            /*Role*/
            el = xml.ElementByLocalName("RoleList");
            if (el != null)
            {
                els = el.ElementsByLocalName(Role.ElementName);
                foreach (var item in els)
                {
                    el = item;
                    var add = new Role(el);
                    this._RoleList.Add(add);
                }
            }
            /*InputEndpoint*/
            el = xml.ElementByLocalName("InputEndpointList");
            if (el != null)
            {
                els = el.ElementsByLocalName(InputEndpoint.ElementName);
                foreach (var item in els)
                {
                    el = item;
                    var add = new InputEndpoint(el);
                    this._InputEndpointList.Add(add);
                }
            }
            /*UpgradeStatus*/
            el = xml.ElementByLocalName(UpgradeStatus.ElementName);
            if (el != null)
            {
                this.UpgradeStatus = new UpgradeStatus(el);
            }
        }

    }
}
